﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GISCore.Geometry;
using GISTools;

namespace GISTools.Generators
{
    internal class TileMapGenerator : IMapGenerator
    {
        private Layer Map { get; set; }
        private int TileCount { get; set; }

        internal TileMapGenerator(Layer seed)
            : this(seed, 5) { }

        internal TileMapGenerator(Layer seed, int tileCount)
        {
            Map = seed;
            TileCount = tileCount;
        }

        public Layer Generate()
        {
            var polygons = new List<Polygon>();
            var origs = from poly in Map.GetPolygons()
                        select poly.DeepClone();

            var rndm = new Random();
            
            var bbox = Map.GetBoundingBox();
            double dx = Math.Abs(bbox[0].X - bbox[1].X);
            double dy = Math.Abs(bbox[0].Y - bbox[1].Y);

            for (int i = 1; i <= TileCount; i++)
            {
                foreach (var poly in origs)
                {
                    polygons.Add(_shiftPolygon(poly, i * dx, i * dy));
                }
            }
            polygons.AddRange(origs);
            var newLayer = new Layer(0, polygons);

            Point oldLower = Map.GetBoundingBox()[0];
            Point oldUpper = Map.GetBoundingBox()[1];
            Point upper = new Point(oldUpper.X * (TileCount * dx), oldUpper.Y * (TileCount * dy));

            newLayer.SetBoundingBox(oldLower, upper);

            return newLayer;
        }

        private Polygon _shiftPolygon(Polygon p, double dx, double dy)
        {
            Point delta = new Point(dx, dy);
            // map all the lines in the polygon p
            // to new lines shifted by the delta x and delta y
            var lines = from line in p.getLines()
                        where line != null
                        select new Line(line.Start + delta, line.End + delta);
            
            var holes = from hole in p.holes
                        where hole != null
                        select new Hole(0, (
                            from line in hole.getLines()
                            where line != null
                            select new Line(line.Start + delta, line.End + delta)).ToList());
            
            var newPoly = new Polygon(0, lines.ToList());
            newPoly.holes = holes.ToList();

            return newPoly;
        }
    }
}

